package com.webImp.bdd;

import static com.webImp.bdd.DAOUtilitaire.fermeturesSilencieuses;
import static com.webImp.bdd.DAOUtilitaire.initialisationRequetePreparee;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.webImp.beans.User;

public class UserDAO
{
	private static final String SQL_SELECT = "SELECT id, nom, prenom, adresse, telephone, email, image FROM Client ORDER BY id";
	private static final String SQL_SELECT_PAR_ID = "SELECT id, nom, prenom, adresse, telephone, email, image FROM Client WHERE id = ?";
	private static final String SQL_INSERT = "INSERT INTO Client (nom, prenom, adresse, telephone, email, image) VALUES (?, ?, ?, ?, ?, ?)";
	private static final String SQL_DELETE_PAR_ID = "DELETE FROM Client WHERE id = ?";

	private DAOFactory daoFactory;

	UserDAO(DAOFactory daoFactory)
	{
		this.daoFactory = daoFactory;
	}

	/* Implémentation de la méthode définie dans l'interface ClientDao */
	public User trouver(long id) throws DAOException
	{
		return trouver(SQL_SELECT_PAR_ID, id);
	}

	/* Implémentation de la méthode définie dans l'interface ClientDao */
	public void creer(User client) throws DAOException
	{
		Connection connexion = null;
		PreparedStatement preparedStatement = null;
		ResultSet valeursAutoGenerees = null;

		try
		{
			connexion = daoFactory.getConnection();
			preparedStatement = initialisationRequetePreparee(connexion,
					SQL_INSERT, true, client.getNom(), client.getPrenom(),
					client.getAdresse(), client.getTelephone(),
					client.getEmail(), client.getImage());
			int statut = preparedStatement.executeUpdate();
			if (statut == 0) { throw new DAOException(
					"Échec de la création du client, aucune ligne ajoutée dans la table."); }
			valeursAutoGenerees = preparedStatement.getGeneratedKeys();
			if (valeursAutoGenerees.next())
			{
				client.setId(valeursAutoGenerees.getLong(1));
			}
			else
			{
				throw new DAOException(
						"Échec de la création du client en base, aucun ID auto-généré retourné.");
			}
		}
		catch (SQLException e)
		{
			throw new DAOException(e);
		}
		finally
		{
			fermeturesSilencieuses(valeursAutoGenerees, preparedStatement,
					connexion);
		}
	}

	/* Implémentation de la méthode définie dans l'interface ClientDao */
	public List<User> lister() throws DAOException
	{
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		List<User> clients = new ArrayList<User>();

		try
		{
			connection = daoFactory.getConnection();
			preparedStatement = connection.prepareStatement(SQL_SELECT);
			resultSet = preparedStatement.executeQuery();
			while (resultSet.next())
			{
				clients.add(map(resultSet));
			}
		}
		catch (SQLException e)
		{
			throw new DAOException(e);
		}
		finally
		{
			fermeturesSilencieuses(resultSet, preparedStatement, connection);
		}

		return clients;
	}

	/* Implémentation de la méthode définie dans l'interface ClientDao */
	public void supprimer(User client) throws DAOException
	{
		Connection connexion = null;
		PreparedStatement preparedStatement = null;

		try
		{
			connexion = daoFactory.getConnection();
			preparedStatement = initialisationRequetePreparee(connexion,
					SQL_DELETE_PAR_ID, true, client.getId());
			int statut = preparedStatement.executeUpdate();
			if (statut == 0)
			{
				throw new DAOException(
						"Échec de la suppression du client, aucune ligne supprimée de la table.");
			} 
			else client.setId(null);
		}
		catch (SQLException e)
		{
			throw new DAOException(e);
		}
		finally
		{
			fermeturesSilencieuses(preparedStatement, connexion);
		}
	}

	/*
	 * Méthode générique utilisée pour retourner un client depuis la base de
	 * données, correspondant à la requête SQL donnée prenant en paramètres les
	 * objets passés en argument.
	 */
	private User trouver(String sql, Object... objets) throws DAOException
	{
		Connection connexion = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		User client = null;

		try
		{
			/* Récupération d'une connexion depuis la Factory */
			connexion = daoFactory.getConnection();
			/*
			 * Préparation de la requête avec les objets passés en arguments
			 * (ici, uniquement un id) et exécution.
			 */
			preparedStatement = initialisationRequetePreparee(connexion, sql,
					false, objets);
			resultSet = preparedStatement.executeQuery();
			/* Parcours de la ligne de données retournée dans le ResultSet */
			if (resultSet.next())
			{
				client = map(resultSet);
			}
		}
		catch (SQLException e)
		{
			throw new DAOException(e);
		}
		finally
		{
			fermeturesSilencieuses(resultSet, preparedStatement, connexion);
		}

		return client;
	}

	/*
	 * Simple méthode utilitaire permettant de faire la correspondance (le
	 * mapping) entre une ligne issue de la table des clients (un ResultSet) et
	 * un bean Client.
	 */
	private static User map(ResultSet resultSet) throws SQLException
	{
		User client = new User();
		client.setId(resultSet.getLong("id"));
		client.setNom(resultSet.getString("nom"));
		client.setPrenom(resultSet.getString("prenom"));
		client.setAdresse(resultSet.getString("adresse"));
		client.setTelephone(resultSet.getString("telephone"));
		client.setEmail(resultSet.getString("email"));
		client.setImage(resultSet.getString("image"));
		return client;
	}

}